package com.nrgedge.magnolia.servlet;

import info.magnolia.context.MgnlContext;
import info.magnolia.objectfactory.Components;
import info.magnolia.rendering.engine.AppendableOnlyOutputProvider;
import info.magnolia.rendering.engine.RenderException;
import info.magnolia.rendering.engine.RenderingEngine;

import java.io.InputStream;
import java.io.StringWriter;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

import javax.jcr.Node;
import javax.jcr.NodeIterator;
import javax.jcr.PathNotFoundException;
import javax.jcr.RepositoryException;
import javax.jcr.ValueFormatException;
import javax.jcr.query.InvalidQueryException;
import javax.jcr.query.Query;
import javax.servlet.http.HttpServletRequest;

import com.nrgedge.magnolia.servlet.AbstractHoganPrecompileServlet;

public class MagnoliaHoganPrecompileServlet extends AbstractHoganPrecompileServlet {

	private static final long serialVersionUID = -3777254171852059516L;

	private static final String COMPILED_HOGAN_TEMPLATE_NAME_PROPERTY = "compiledTemplate";

	private static final String QUERY = "SELECT * FROM nt:base WHERE " + COMPILED_HOGAN_TEMPLATE_NAME_PROPERTY + " IS NOT NULL";
	
	public List<Node> getTemplateNodes() {
		final List<Node> results = new ArrayList<Node>();

		final String queryString  = QUERY; 
		
		try {
			final Query query = MgnlContext.getJCRSession("website").getWorkspace().getQueryManager().createQuery(queryString, "sql");
			final NodeIterator nodes = query.execute().getNodes();

			while (nodes.hasNext()) {
				results.add(nodes.nextNode());
			}
		} catch (InvalidQueryException e) {
			this.log.error("InvalidQueryException in getNodes()", e);
		} catch (RepositoryException e) {
			this.log.error("RepositoryException in getNodes()", e);
		}
		return results;
	}

	public String getRenderedWebsiteContentAsString(final Node node) {
		final RenderingEngine engine = Components.getComponentProvider().getComponent(RenderingEngine.class);
		final StringWriter writer = new StringWriter();

		try {
			engine.render(node, new AppendableOnlyOutputProvider(writer));
			return writer.toString();
		} catch (RenderException e) {
			this.log.error("RenderException in getRenderedWebsiteContentAsString()", e);
		}
		return null;
	}

	@Override
	public InputStream getHoganLibrary(final HttpServletRequest request) {
		return getServletContext().getResourceAsStream("/docroot/js-template-support/js/hogan-2.0.0.min.js");
	}

	@Override
	public Map<String, String> getTemplates(final HttpServletRequest request) {
		final Map<String, String> templates = new LinkedHashMap<String, String>();

		final List<Node> nodes = getTemplateNodes();
		

		for (final Node node : nodes) {
			try {
				final String templateName = node.getPath().substring(1).replace("/", "_");
				final String template = getRenderedWebsiteContentAsString(node);

				templates.put(templateName, template);

			} catch (ValueFormatException e) {
				this.log.error("ValueFormatException in getTemplates()", e);
			} catch (PathNotFoundException e) {
				this.log.error("PathNotFoundException in getTemplates()", e);
			} catch (RepositoryException e) {
				this.log.error("RepositoryException in getTemplates()", e);
			}
		}

		return templates;
	}
}
